﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel.Design;
using System.ComponentModel;

namespace Ajaxna.Designers
{
    /// <summary>
    /// This class is a Genenric implementation of the ITypeDescriptorContext interface.
    /// This class can be used as the first parameter to a UITypeEditors EditValue method,
    /// especially when implementing design time verbs.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class TypeDescriptorContext<T> : ITypeDescriptorContext where T : IDesigner, IServiceProvider
    {
        private T _designer;
        private PropertyDescriptor _propertyDescriptor;

        public TypeDescriptorContext(T designer, PropertyDescriptor propertyDescriptor)
        {
            _designer = designer;
            _propertyDescriptor = propertyDescriptor;
        }

        private IComponentChangeService ComponentChangeService
        {
            get
            {
                return (IComponentChangeService)this.GetService(typeof(IComponentChangeService));
            }
        }

        #region IServiceProvider Members

        public object GetService(Type serviceType)
        {
            return _designer.GetService(serviceType);
        }

        #endregion


        #region ITypeDescriptorContext Members

        public IContainer Container
        {
            get { return _designer.Component.Site.Container; }
        }

        public object Instance
        {
            get { return _designer.Component; }
        }

        public void OnComponentChanged()
        {
            if (this.ComponentChangeService != null)
            {
                this.ComponentChangeService.OnComponentChanged(
                    this.Instance, this.PropertyDescriptor, null, null
                ); // Is it right to send nulls for old and new values?
            }
        }

        public bool OnComponentChanging()
        {
            if (this.ComponentChangeService != null)
            {
                try
                {
                    this.ComponentChangeService.OnComponentChanging(this.Instance, this.PropertyDescriptor);
                }
                catch (CheckoutException ex)
                {
                    if (ex == CheckoutException.Canceled)
                        return false;
                    throw ex;
                }
            }
            return true;
        }

        public PropertyDescriptor PropertyDescriptor
        {
            get { return _propertyDescriptor; }
        }

        #endregion


    }
}
